package com.chat.module.client;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.chat.comment.core.ResponseResult;
import com.chat.comment.util.NettyAttrUtil;
import com.chat.config.dao.RedisUtils;
import com.chat.config.web.webSocket.handler.WebSocketChannelManager;
import com.chat.module.message.service.impl.WsMessageService;
import com.chat.module.message.service.impl.ChatInfoLogServiceImpl;
import com.chat.module.user.service.impl.UserServiceImpl;
import com.comment.pojo.domain.chat.WsMessage;

import com.comment.pojo.domain.logic.core.PvpMatch;
import com.comment.pojo.domain.logic.core.PvpRoom;
import com.comment.dubbo.service.PlayerMatchService;
import com.comment.dubbo.service.PvpRoomService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.chat.config.web.webSocket.SessionConstant.CHANEL_INFO_KEY;

/**
 * 客户端信息处理服务
 */
@Slf4j
@Service
public class ClientMessageServiceImpl {
    private final RedisUtils redisUtils = RedisUtils.redisUtils();

    @DubboReference
    private PlayerMatchService playerMatchService;
    @DubboReference
    private PvpRoomService pvpRoomService;
    @Resource
    private WsMessageService wsMessageService;
    private final WsMessageService chatService = SpringUtil.getBean(WsMessageService.class);
    private final UserServiceImpl UserService = SpringUtil.getBean(UserServiceImpl.class);
    private final ChatInfoLogServiceImpl chatInfoLogService = SpringUtil.getBean(ChatInfoLogServiceImpl.class);


    public void messageLinkByCode(ChannelHandlerContext ctx, WsMessage wsMessage) {
        try {
            Integer code = wsMessage.getCode();
            Long sendUserId = (Long) ctx.channel().attr(CHANEL_INFO_KEY).get().getUserId();
            if (code < 20) {
                wsMessageService.messageLogByCode(wsMessage);
            }
            Set<Long> receiverUserIdList = wsMessage.getReceiverUserIdList();
            switch (code) {
                case 1: // 私聊
                    if (receiverUserIdList.isEmpty()) {
                        chatService.sendMessageToUser(sendUserId, ResponseResult.error("接收者列表为空"));
                    }


                    Long next = receiverUserIdList.iterator().next();
                    try {
                        UserService.checkBothSides(sendUserId, next);
                    } catch (RuntimeException e) {
                        chatService.sendMessageToUser(sendUserId, ResponseResult.error(e.getMessage() + ",无法聊天"));
                        break;
                    }
                    UserService.tryLogRecentContacts(wsMessage, next);
                    // 发送消息
                    wsMessage.setReceiverUserIdList(null);
                    log.info("私聊发送者:{}，私聊接收者:{},私聊消息:{}", sendUserId, next, wsMessage);
                    chatService.sendMessageToUser(next, wsMessage);
                    chatService.sendMessageToUser(sendUserId, wsMessage);
                    break;
                // 2. 世界频道
                case 2:
                    // 向连接上来的客户端广播消息
                    chatService.sendMessageAll(wsMessage);
                    break;
                // 4.PONG 心跳机制
                case 4:
                    Channel channel = ctx.channel();
                    // 更新心跳时间
                    NettyAttrUtil.refreshLastHeartBeatTime(channel);
                    break;
                // 5.系统邮件 玩家点击系统邮件时候触发
                case 5:
                    // 系统
                    break;
                // 6.局内
                case 6: {
                    PvpMatch pvpMatch = playerMatchService.obtainOwnerMatch(wsMessage.getSendUserId());
                    Set<Long> playerIds = pvpMatch.getPlayerIds();
                    for (Long playerId : playerIds) {
                        log.info("发送者:{},接收者:{},消息:{}", sendUserId, playerId, wsMessage);
                        chatService.sendMessageToUser(playerId, wsMessage);
                    }
                    break;
                }
                case 7: // 组队聊天
                    PvpRoom pvpRoom = pvpRoomService.selectMyJoinRoom(sendUserId);
                    for (Long playerId : pvpRoom.getPlayers()) {
                        Channel chanelToUser = WebSocketChannelManager.channelMap.get(playerId);
                        chanelToUser.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(wsMessage)));
                    }
                    break;
                default:
            }
        } catch (Exception e) {
            log.error("转发消息异常:", e);
        }
    }
}
